package top.lishuoboy.hibernate.validator.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Path;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author lishuoboy
 * @date 2024.10.19 0:52
 */
@Slf4j
public class ConstraintViolationSetUtil {

    /** 将违反约束从平面结构转为按字段聚合的Map */
    public static <T> Map<String, List<String>> toMap(Set<ConstraintViolation<T>> constraintViolationSet) {
        Map<String, List<String>> constraintViolationMap = new LinkedHashMap<>();
        for (ConstraintViolation<T> cv : constraintViolationSet) {
            Class<?> rootBeanClass = cv.getRootBeanClass();
            Path propertyPath = cv.getPropertyPath();
            Object invalidValue = cv.getInvalidValue();
            String message = cv.getMessage();
            String key = StrUtil.format("{}-{}({})", rootBeanClass.getSimpleName(), propertyPath, invalidValue);
            if (constraintViolationMap.containsKey(key)) {
                constraintViolationMap.get(key).add(message);
            } else {
                constraintViolationMap.put(key, ListUtil.list(false, message));
            }
        }
        return constraintViolationMap;
    }

    /** 将违反约束从平面结构转为按字段聚合的Map，并输出 */
    public static <T> void toMapAndPrint(Set<ConstraintViolation<T>> constraintViolationSet) {
        Map<String, List<String>> map = toMap(constraintViolationSet);
        if (MapUtil.isEmpty(map)) {
            log.info("校验通过");
        } else {
            log.warn("校验失败：{}", map);
        }
    }
}
